home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / timidsrc.zip / pm_c.c < prev    next >
C/C++ Source or Header  |  1997-05-18  |  23KB  |  735 lines

  1. /*
  2.  
  3.     TiMidity -- Experimental MIDI to WAVE converter
  4.     Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
  5.  
  6.      This program is free software; you can redistribute it and/or modify
  7.      it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.      (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.      GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20.     pm_c.c: This is the interface for OS/2 Presentation Manager
  21.     Copyright (C) 1997 Darwin O'Connor <doconno@cc.umanitoba.ca>    
  22. */
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <stdarg.h>
  27. #define INCL_DOSSEMAPHORES
  28. #define INCL_DOSPROCESS
  29. #define INCL_WINMESSAGEMGR
  30. #define INCL_WINLISTBOXES
  31. #define INCL_WINSTDFILE
  32. #define INCL_WINBUTTONS
  33. #define INCL_WINPOINTERS
  34. #define INCL_WINFRAMEMGR
  35. #define INCL_WINTIMER
  36. #define INCL_WINSTDSLIDER
  37. #define INCL_WINMENUS
  38. #define INCL_WINSYS
  39. #define INCL_WINWINDOWMGR
  40. #define INCL_WINCIRCULARSLIDER
  41. #define INCL_WINMLE
  42. #define INCL_WINSHELLDATA
  43. #define INCL_MCIOS2
  44. #include <os2.h>
  45. #include <os2me.h>
  46. #include "config.h"
  47. #include "controls.h"
  48. #include "instrum.h"
  49. #include "playmidi.h"
  50. #include "output.h"
  51. #include "pm_c.h"
  52.  
  53. extern MCI_AMP_OPEN_PARMS AmpOpenParms;
  54. HWND Frame;
  55. HAB Timidab,
  56.     PMab;
  57. HMQ Timidmq,
  58.     PMmq;
  59. HWND FILELISTBOXwin,
  60.      PLAYwin,
  61.      PAUSEwin,
  62.      STOPwin,
  63.      FILENAMETEXTwin,
  64.      AUTOPLAYwin,
  65.      CURRTIMEwin,
  66.      TOTALTIMEwin,
  67.      POSSLIDERwin,
  68.      RESTARTwin,
  69.      SKIPwin,
  70.      BACKwin,
  71.      PREVwin,
  72.      FFWDwin,
  73.      INFO_TEXTwin;
  74.    /*     VOLUMEwin,
  75.      BUFFLEFTwin,
  76.      PRIORITYwin;*/
  77. HEV pausesem;
  78. int paused = 0;
  79. MCI_GENERIC_PARMS GenericParms = {0};
  80. unsigned int currtime;
  81. int oldtime,
  82.     sliderwidth,
  83.     maxtime,
  84.     maxtimidtime,
  85.     drawticks = 0,
  86.     timeoffset=0,
  87.     manualslide=1,
  88.    /*    manualvolume=1,*/
  89.     playing=0,
  90.     sectime,
  91.     mintime,
  92.     thinghidden=0,
  93.     infoboxshown=0;
  94. POINTL tickorg;
  95. MCI_STATUS_PARMS gettimeparms = {NULLHANDLE,0,MCI_STATUS_POSITION,0};
  96. USHORT mmos2DeviceID;
  97. extern int numout;
  98. extern PTIB ptib;
  99. typedef struct {
  100.    void *next;
  101.    char line[200];
  102. } msgnode;
  103. msgnode *msgstart=NULL;
  104. msgnode *msgend=NULL;
  105. char mleio[200];
  106. IPT point;
  107. LONG logotime;
  108.  
  109. #define PLAY_DART 1
  110. #define PLAY_MMOS2 2
  111.  
  112. #define UM_EXIT (WM_USER+1)
  113. #define UM_PLAY (WM_USER+2)
  114. #define UM_PAUSE (WM_USER+3)
  115. #define UM_STOP (WM_USER+4)
  116. #define UM_RESTART (WM_USER+5)
  117. #define UM_SKIP (WM_USER+6)
  118. #define UM_JUMPTO (WM_USER+7)
  119. #define UM_PREV (WM_USER+8)
  120. #define UM_STEP (WM_USER+9)
  121. #define UM_VOLUME (WM_USER+10)
  122. #define UM_MMOS2_DONE (WM_USER+11)
  123. #define UM_RESUME (WM_USER+12)
  124.  
  125. unsigned int muldiv(unsigned int a, unsigned int b, unsigned int c);
  126.  
  127. static void ctl_refresh(void) {}
  128. static void ctl_total_time(int tt);
  129. static void ctl_master_volume(int mv);
  130. static void ctl_file_name(char *name);
  131. static void ctl_current_time(int ct) {}
  132. static void ctl_note(int v) {}
  133. static void ctl_program(int ch, int val) {}
  134. static void ctl_volume(int channel, int val) {}
  135. static void ctl_expression(int channel, int val) {}
  136. static void ctl_panning(int channel, int val) {}
  137. static void ctl_sustain(int channel, int val) {}
  138. static void ctl_pitch_bend(int channel, int val) {}
  139. static void ctl_reset(void) {}
  140. static int ctl_open(int using_stdin, int using_stdout);
  141. static void ctl_close(void);
  142. static int ctl_read(int32 *valp);
  143. static int cmsg(int type, int verbosity_level, char *fmt, ...);
  144. static void ctl_pass_playing_list(int number_of_files, char *list_of_files[]);
  145.  
  146. #define ctl pm_control_mode
  147.  
  148. ControlMode ctl= 
  149. {
  150.   "OS/2-PM interface", 'p',
  151.   1,0,0,
  152.   ctl_open, ctl_pass_playing_list, ctl_close, ctl_read, cmsg,
  153.   ctl_refresh, ctl_reset, ctl_file_name, ctl_total_time, ctl_current_time, 
  154.   ctl_note, 
  155.   ctl_master_volume, ctl_program, ctl_volume, 
  156.   ctl_expression, ctl_panning, ctl_sustain, ctl_pitch_bend
  157. };
  158.  
  159. MRESULT AboutProc(HWND wnd, ULONG msg, MPARAM mp1, MPARAM mp2) {
  160.    switch (msg) {
  161.    case WM_INITDLG:
  162.       if (logotime!=-1) WinStartTimer(PMab,wnd,667,logotime);
  163.       return FALSE;
  164.    case WM_TIMER:
  165.       WinPostMsg(wnd,WM_CLOSE,0,0);
  166.       return 0;
  167.    case WM_CLOSE:
  168.       WinStopTimer(PMab,wnd,667);
  169.    }
  170.    return (WinDefDlgProc(wnd,msg,mp1,mp2));  
  171. }
  172.  
  173. MRESULT InfoProc(HWND wnd, ULONG msg, MPARAM mp1, MPARAM mp2) {
  174.    msgnode *curr;
  175.    int length;
  176.    
  177.    switch (msg) {
  178.    case WM_INITDLG:
  179.       INFO_TEXTwin=WinWindowFromID(wnd,INFO_TEXT);
  180.       WinSendMsg(INFO_TEXTwin,MLM_SETIMPORTEXPORT,MPFROMP(mleio),MPFROMLONG(122));
  181.       curr=msgstart;
  182.       point=-1;
  183.       while (curr) {
  184.      length=strlen(strcpy(mleio,curr->line));
  185.      mleio[length]='\r';
  186.      mleio[length+1]=' ';
  187.      mleio[length+2]='\0';
  188.      WinSendMsg(INFO_TEXTwin,MLM_IMPORT,MPFROMP(&point),MPFROMLONG(length+2));
  189.      curr=curr->next;
  190.       }
  191.       infoboxshown=1;
  192.       return FALSE;
  193.    case WM_CLOSE:
  194.       infoboxshown=0;
  195.       break;
  196.    }
  197.    return (WinDefDlgProc(wnd,msg,mp1,mp2));
  198. }
  199.  
  200. MRESULT DialogProc(HWND wnd, ULONG msg, MPARAM mp1, MPARAM mp2) {
  201.    SHORT item;
  202.    char *filename;
  203.    HWND dialogwin;
  204.    static FILEDLG fileDlg = {sizeof(FILEDLG),FDS_OPEN_DIALOG | FDS_MULTIPLESEL,
  205.                  0,0,0,"File Open",NULL,NULL,NULL,NULL,NULL,NULL,
  206.                  NULLHANDLE,"*",NULL,0,0,0,0,0};
  207.    static LBOXINFO ListboxInfo = {LIT_END,0,0,0};
  208.    char timestr[7];
  209.    POINTL pnt;
  210.    int even;
  211.    LONG loop;
  212.    int currsec,
  213.        currpos;
  214.    static int oldsec,
  215.               oldpos;
  216.    
  217.    switch (msg) {
  218.    case WM_CLOSE:
  219.       WinPostMsg(Frame,WM_QUIT,0,0);
  220.       break;
  221.    case WM_CONTROL:
  222.       if (mp1==MPFROM2SHORT(FILELISTBOX,LN_ENTER)) {
  223.      item=SHORT1FROMMR(WinSendMsg(FILELISTBOXwin,LM_QUERYSELECTION,
  224.                       MPFROMSHORT(LIT_FIRST),0));
  225.      filename=malloc(100);
  226.      WinSendMsg(FILELISTBOXwin,LM_QUERYITEMTEXT,MPFROM2SHORT(item,100),
  227.             filename);
  228.      WinPostQueueMsg(Timidmq,UM_PLAY,filename,MPFROMLONG(item));
  229.      return 0;
  230.       }
  231.       if (mp1==MPFROM2SHORT(POSSLIDER,SLN_CHANGE) && manualslide) {
  232.      WinPostQueueMsg(Timidmq,UM_JUMPTO,mp2,0);
  233.      return 0;
  234.       }
  235.       /*      if (mp1==MPFROM2SHORT(VOLUME,CSN_CHANGED) && manualvolume) {
  236.      WinPostQueueMsg(Timidmq,UM_VOLUME,mp2,0);
  237.      return 0;
  238.       }*/
  239.       break;
  240.    case WM_COMMAND:
  241.       switch (SHORT1FROMMP(mp1)) {
  242.       case PLAY:
  243.      item=SHORT1FROMMR(WinSendMsg(FILELISTBOXwin,LM_QUERYSELECTION,
  244.                       MPFROMSHORT(LIT_FIRST),0));
  245.      filename=malloc(100);
  246.      WinSendMsg(FILELISTBOXwin,LM_QUERYITEMTEXT,MPFROM2SHORT(item,100),
  247.             filename);
  248.      WinPostQueueMsg(Timidmq,UM_PLAY,filename,MPFROMLONG(item));
  249.      return 0;
  250.       case PAUSE:
  251.      if (playing==PLAY_DART) {
  252.         if (paused)
  253.            DosPostEventSem(pausesem);
  254.         else {
  255.            DosResetEventSem(pausesem,&loop);
  256.            WinPostQueueMsg(Timidmq,UM_PAUSE,0,0);
  257.         }
  258.      }
  259.      paused=!paused;
  260.      if (playing==PLAY_DART) {
  261.         mciSendCommand(AmpOpenParms.usDeviceID,paused?MCI_PAUSE:MCI_RESUME,
  262.                MCI_WAIT,&GenericParms,0);
  263.      }
  264.      if (playing==PLAY_MMOS2) {
  265.         WinPostQueueMsg(Timidmq,paused?UM_PAUSE:UM_RESUME,0,0);
  266.      }
  267.      WinSetWindowText(PAUSEwin,paused?"Res~ume":"Pa~use");
  268.      return 0;
  269.       case STOP:
  270.      WinPostQueueMsg(Timidmq,UM_STOP,0,0);
  271.      return 0;
  272.       case OPEN:
  273.      dialogwin=WinFileDlg(HWND_DESKTOP,Frame,&fileDlg);
  274.      if (fileDlg.lReturn==DID_OK) {
  275.         ListboxInfo.ulItemCount=fileDlg.ulFQFCount;
  276.         WinSendMsg(FILELISTBOXwin,LM_INSERTMULTITEMS,&ListboxInfo,
  277.                fileDlg.papszFQFilename);
  278.      }
  279.      return 0;
  280.       case RESTART:
  281.      WinPostQueueMsg(Timidmq,UM_RESTART,0,0);
  282.      return 0;
  283.       case SKIP:
  284.      WinPostQueueMsg(Timidmq,UM_SKIP,0,0);
  285.      return 0;
  286.       case PREV:
  287.      WinPostQueueMsg(Timidmq,UM_PREV,0,0);
  288.      return 0;
  289.       case FFWD:
  290.      WinPostQueueMsg(Timidmq,UM_STEP,MPFROMSHORT(TRUE),0);
  291.      return 0;
  292.       case BACK:
  293.      WinPostQueueMsg(Timidmq,UM_STEP,MPFROMSHORT(FALSE),0);
  294.      return 0;
  295.       case INFOBUTTON:
  296.      WinLoadDlg(HWND_DESKTOP,HWND_DESKTOP,InfoProc,NULLHANDLE,INFO,
  297.             NULL);
  298.      return 0;
  299.       }
  300.       break;
  301.    case WM_TIMER:
  302.       /*      WinSetWindowText(BUFFLEFTwin,_itoa(numout,timestr,10));
  303.       WinSetWindowText(PRIORITYwin,_ultoa(ptib->tib_ptib2->tib2_ulpri,timestr,10));*/
  304.       if (playing==PLAY_MMOS2) {
  305.      mciSendCommand(mmos2DeviceID,MCI_STATUS,
  306.             MCI_WAIT | MCI_STATUS_ITEM,&gettimeparms,0);
  307.      currtime=gettimeparms.ulReturn;
  308.       }
  309.       if (SHORT1FROMMP(mp1)==666 && currtime!=oldtime) {
  310.      currsec=((currtime/sectime) % 60);
  311.      if (currsec!=oldsec) {        
  312.         sprintf(timestr,"%d:%02d",currtime/mintime,currsec);
  313.         WinSetWindowText(CURRTIMEwin,timestr);
  314.         oldsec=currsec;
  315.      }
  316.      currpos=muldiv(currtime,sliderwidth,maxtime);
  317.      if (currpos!=oldpos) {
  318.         manualslide=0;
  319.         WinSendMsg(POSSLIDERwin,SLM_SETSLIDERINFO,
  320.                MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE),
  321.                MPFROMLONG(currpos));
  322.         manualslide=1;
  323.         oldpos=currpos;
  324.      }
  325.      oldtime=currtime;
  326.       }
  327.       return 0;
  328.    case WM_DRAWITEM:
  329.       if (SHORT1FROMMP(mp1)==POSSLIDER && drawticks && ((POWNERITEM)mp2)->idItem==SDA_BACKGROUND) {
  330.      WinFillRect(((POWNERITEM)mp2)->hps,&((POWNERITEM)mp2)->rclItem,
  331.              SYSCLR_DIALOGBACKGROUND);
  332.      GpiSetColor(((POWNERITEM)mp2)->hps,CLR_BLACK);
  333.      loop=0;
  334.      even=1;
  335.      while (loop<=maxtime) {
  336.         pnt.x=tickorg.x+muldiv(loop,sliderwidth,maxtime);
  337.         pnt.y=tickorg.y;
  338.         GpiMove(((POWNERITEM)mp2)->hps,&pnt);
  339.         pnt.y-=even?5:3;
  340.         GpiLine(((POWNERITEM)mp2)->hps,&pnt);
  341.         even=!even;
  342.         loop+=mintime >> 1;
  343.      }
  344.      return MRFROMLONG(TRUE);
  345.       } else return FALSE;
  346.    case MM_MCINOTIFY:
  347.       WinPostQueueMsg(Timidmq,msg,mp1,mp2);
  348.       return 0;
  349.    case MM_MCIPASSDEVICE:
  350.       if (AmpOpenParms.usDeviceID==SHORT1FROMMP(mp1) && playing==PLAY_DART) {
  351.      if (SHORT1FROMMP(mp2)==MCI_GAINING_USE) {
  352.         mciSendCommand(AmpOpenParms.usDeviceID,MCI_ACQUIREDEVICE,MCI_WAIT,
  353.                &GenericParms,0);
  354.         DosPostEventSem(pausesem);
  355.         paused=0;
  356.      } else {
  357.         DosResetEventSem(pausesem,&loop);
  358.         WinPostQueueMsg(Timidmq,UM_PAUSE,0,0);
  359.         paused=1;
  360.      }
  361.      return 0;
  362.       }
  363.       break;
  364.    case WM_MINMAXFRAME:
  365.       if (thinghidden) {
  366.      WinShowWindow(BACKwin,TRUE);
  367.      thinghidden=0;
  368.      return FALSE;
  369.       }
  370.       if ((((PSWP)mp1)->fl & SWP_MINIMIZE) && !thinghidden) {
  371.      WinShowWindow(BACKwin,FALSE);
  372.      thinghidden=1;
  373.      return FALSE;
  374.       }
  375.       break;
  376.    }
  377.    return (WinDefDlgProc(wnd,msg,mp1,mp2));
  378. }
  379.  
  380. void pmmain() {
  381.    QMSG     qmsg;
  382.    MRESULT  messret;
  383.    ULONG junk;
  384.  
  385.    PMab=WinInitialize(0);
  386.    PMmq=WinCreateMsgQueue(PMab,0);
  387.    logotime=PrfQueryProfileInt(HINI_PROFILE,"PM_ControlPanel",
  388.                    "LogoDisplayTime",0);
  389.    if (logotime) WinDlgBox(HWND_DESKTOP,HWND_DESKTOP,AboutProc,NULLHANDLE,
  390.                DLG_ABOUT,NULL);
  391.    Frame=WinLoadDlg(HWND_DESKTOP,HWND_DESKTOP,DialogProc,NULLHANDLE,MAINWIN,
  392.             NULL);
  393.    FILELISTBOXwin=WinWindowFromID(Frame,FILELISTBOX);
  394.    DosPostEventSem(pausesem);
  395.    PLAYwin=WinWindowFromID(Frame,PLAY);
  396.    PAUSEwin=WinWindowFromID(Frame,PAUSE);
  397.    STOPwin=WinWindowFromID(Frame,STOP);
  398.    RESTARTwin=WinWindowFromID(Frame,RESTART);
  399.    SKIPwin=WinWindowFromID(Frame,SKIP);
  400.    BACKwin=WinWindowFromID(Frame,BACK);
  401.    PREVwin=WinWindowFromID(Frame,PREV);
  402.    FFWDwin=WinWindowFromID(Frame,FFWD);
  403.    FILENAMETEXTwin=WinWindowFromID(Frame,FILENAMETEXT);
  404.    AUTOPLAYwin=WinWindowFromID(Frame,AUTOPLAY);
  405.    CURRTIMEwin=WinWindowFromID(Frame,CURRTIME);
  406.    TOTALTIMEwin=WinWindowFromID(Frame,TOTALTIME);
  407.    POSSLIDERwin=WinWindowFromID(Frame,POSSLIDER);
  408.    /*   BUFFLEFTwin=WinWindowFromID(Frame,BUFFLEFT);
  409.    PRIORITYwin=WinWindowFromID(Frame,PRIORITY);*/
  410.    sliderwidth=SHORT2FROMMR(WinSendMsg(POSSLIDERwin,SLM_QUERYSLIDERINFO,
  411.                        MPFROM2SHORT(SMA_SLIDERARMPOSITION,
  412.                             SMA_RANGEVALUE),0))-1;
  413.    messret=WinSendMsg(POSSLIDERwin,SLM_QUERYTICKPOS,MPFROMSHORT(0),0);
  414.    tickorg.x=SHORT1FROMMR(messret);tickorg.y=SHORT2FROMMR(messret);
  415.    /*   VOLUMEwin=WinWindowFromID(Frame,VOLUME);
  416.    WinSendMsg(VOLUMEwin,CSM_SETRANGE,MPFROMSHORT(0),MPFROMSHORT(100));
  417.    WinSendMsg(VOLUMEwin,CSM_SETINCREMENT,MPFROMSHORT(10),MPFROMSHORT(2));
  418.    WinSendMsg(VOLUMEwin,CSM_SETVALUE,MPFROMSHORT(amplification),0);*/
  419.    WinSendMsg(Frame,WM_SETICON,(MPARAM)WinLoadPointer(HWND_DESKTOP,
  420.               NULLHANDLE,MAINWIN),NULL);
  421.    while(WinGetMsg(PMab,&qmsg,(HWND)NULL,0,0))
  422.       WinDispatchMsg(PMab,&qmsg);
  423.    DosResetEventSem(pausesem,&junk);
  424.    WinPostQueueMsg(Timidmq,UM_EXIT,0,0);
  425.    WinDismissDlg(Frame,TRUE);
  426.    if (infoboxshown) WinDismissDlg(INFO_TEXTwin,TRUE);
  427.    WinDestroyMsgQueue(PMmq);
  428.    WinTerminate(PMab);
  429.    if (DosWaitEventSem(pausesem,10000)==640) {
  430. /*      WinMessageBox(HWND_DESKTOP,NULLHANDLE,
  431.             "The Timidity thread is not responding because of some bug in the program. However, the program will force itself to end.",
  432.             "Timidity for OS/2",0,MB_OK | MB_ERROR | MB_MOVEABLE);
  433.       WinDestroyMsgQueue(PMmq);
  434.       WinTerminate(PMab);*/
  435.       DosExit(EXIT_PROCESS,0);
  436.    }
  437. }
  438.  
  439. int playmmos2file(char *filename) {
  440.    MCI_AMP_OPEN_PARMS mmos2openparms = {Frame,0,0,NULL,filename,NULL,NULL};
  441.    MCI_PLAY_PARMS playparms = {Frame,0,0};
  442.    MCI_GENERIC_PARMS genericparms = {Frame};
  443.    MCI_SEEK_PARMS seekparms = {Frame,0};
  444.    ULONG rc;
  445.    QMSG qmsg;
  446.    MCI_STATUS_PARMS mcistatusparms = {Frame,0,MCI_STATUS_LENGTH,0};
  447.    char timestr[8];
  448.    int returnval=0;
  449.  
  450. #define PLAYUSER 22   
  451.    
  452.    rc=mciSendCommand(0,MCI_OPEN,MCI_WAIT | MCI_OPEN_ELEMENT | MCI_READONLY,
  453.              &mmos2openparms,0);
  454.    mmos2DeviceID=mmos2openparms.usDeviceID;
  455.    WinSetWindowText(FILENAMETEXTwin,filename);
  456.    rc=mciSendCommand(mmos2openparms.usDeviceID,MCI_STATUS,
  457.           MCI_WAIT | MCI_STATUS_ITEM,&mcistatusparms,0);
  458.    if (rc==MCIERR_SUCCESS) return RC_ERROR;
  459.    maxtime=mcistatusparms.ulReturn;
  460.    sectime=3000;
  461.    mintime=180000;
  462.    sprintf(timestr,"%ld:%02ld",mcistatusparms.ulReturn/180000,
  463.        (mcistatusparms.ulReturn/3000)%60);
  464.    WinSetWindowText(TOTALTIMEwin,timestr);
  465.    drawticks=1;
  466.    WinInvalidateRect(POSSLIDERwin,NULL,FALSE);
  467.    playing=PLAY_MMOS2;
  468.    rc=mciSendCommand(mmos2openparms.usDeviceID,MCI_PLAY,MCI_NOTIFY,&playparms,
  469.              PLAYUSER);
  470.    do {
  471.       WinWaitMsg(Timidab,0,0);
  472.       WinPeekMsg(Timidab,&qmsg,NULLHANDLE,0,0,0);
  473.       switch(qmsg.msg) {
  474.       case MM_MCINOTIFY:
  475.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  476.      if (qmsg.mp1==MPFROM2SHORT(MCI_NOTIFY_SUCCESSFUL,PLAYUSER)) {
  477.         returnval=RC_TUNE_END;
  478.      }
  479.      break;
  480.       case UM_STOP:
  481.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  482.       case UM_EXIT:
  483.      returnval=RC_QUIT;
  484.      break;
  485.       case UM_PLAY:
  486.      returnval=RC_LOAD_FILE;
  487.      break;
  488.       case UM_RESTART:
  489.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  490.      rc=mciSendCommand(mmos2openparms.usDeviceID,MCI_SEEK,
  491.                MCI_WAIT | MCI_TO_START,&seekparms,0);
  492.      if (!paused) rc=mciSendCommand(mmos2openparms.usDeviceID,MCI_PLAY,
  493.                     MCI_NOTIFY,&playparms,PLAYUSER);
  494.      break;
  495.       case UM_SKIP:
  496.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  497.      returnval=RC_NEXT;
  498.      break;
  499.       case UM_JUMPTO:
  500.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  501.      seekparms.ulTo=muldiv(LONGFROMMP(qmsg.mp1),maxtime,sliderwidth);
  502.      rc=mciSendCommand(mmos2openparms.usDeviceID,MCI_SEEK,
  503.                MCI_WAIT | MCI_TO,&seekparms,0);
  504.      if (!paused) rc=mciSendCommand(mmos2openparms.usDeviceID,MCI_PLAY,
  505.                     MCI_NOTIFY,&playparms,PLAYUSER);
  506.      break;
  507.       case UM_PREV:
  508.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  509.      returnval=RC_REALLY_PREVIOUS;
  510.      break;
  511.       case UM_STEP:
  512.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  513.      seekparms.ulTo=(currtime*3)+(SHORT1FROMMP(qmsg.mp1)?3000:-3000);
  514.      rc=mciSendCommand(mmos2openparms.usDeviceID,MCI_SEEK,
  515.                MCI_WAIT | MCI_TO,&seekparms,0);
  516.      if (!paused) rc=mciSendCommand(mmos2openparms.usDeviceID,MCI_PLAY,
  517.                     MCI_NOTIFY,&playparms,PLAYUSER);
  518.      break;
  519.       case UM_PAUSE:
  520.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  521.      rc=mciSendCommand(mmos2openparms.usDeviceID,MCI_PAUSE,MCI_WAIT,
  522.                &genericparms,0);
  523.      break;
  524.       case UM_RESUME:
  525.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  526.      rc=mciSendCommand(mmos2openparms.usDeviceID,MCI_PLAY,MCI_NOTIFY,
  527.                &playparms,PLAYUSER);
  528.      /*     rc=mciSendCommand(mmos2openparms.usDeviceID,MCI_RESUME,MCI_WAIT,
  529.                &genericparms,0);*/
  530.      break;
  531.       default:
  532.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);      
  533.       }
  534.    } while (!returnval);
  535.    mciSendCommand(mmos2openparms.usDeviceID,MCI_STOP,MCI_WAIT,
  536.           &genericparms,0);
  537.    playing=0;
  538.    rc=mciSendCommand(mmos2openparms.usDeviceID,MCI_CLOSE,MCI_WAIT,
  539.              &genericparms,0);
  540.    return returnval;
  541. }   
  542.  
  543. static void ctl_file_name(char *name) {
  544.    WinSetWindowText(FILENAMETEXTwin,name);
  545. }   
  546.      
  547. static void ctl_total_time(int tt) {
  548.    char timestr[8];
  549.  
  550.    sprintf(timestr,"%ld:%02ld",tt/(play_mode->rate*60),(tt/play_mode->rate)%60);
  551.    WinSetWindowText(TOTALTIMEwin,timestr);
  552.    maxtimidtime=tt;
  553.    maxtime=tt;
  554.    sectime=play_mode->rate;
  555.    if (!(play_mode->encoding & PE_MONO)) {sectime*=2; maxtime*=2;}
  556.    if (play_mode->encoding & PE_16BIT) {sectime*=2; maxtime*=2;}
  557.    mintime=60*sectime;
  558.    drawticks=1;
  559.    WinInvalidateRect(POSSLIDERwin,NULL,FALSE);
  560. }
  561.  
  562. static int ctl_open(int using_stdin, int using_stdout) {
  563.    Timidab=WinInitialize(0);
  564.    Timidmq=WinCreateMsgQueue(Timidmq,0);
  565.    DosCreateEventSem(NULL,&pausesem,0,FALSE);
  566.    if (_beginthread(pmmain,NULL,64*1024,NULL)!=-1) ctl.opened=1;
  567.    DosWaitEventSem(pausesem,-1);
  568.    return 0;
  569. }
  570.  
  571. static void ctl_master_volume(int mv) {
  572.    /*   manualvolume=0;
  573.    WinSendMsg(VOLUMEwin,CSM_SETVALUE,MPFROMLONG(mv),0);
  574.    manualvolume=1;*/
  575. }
  576.  
  577. static void ctl_close(void) {
  578.    DosPostEventSem(pausesem);
  579.    DosCloseEventSem(pausesem);
  580. }
  581.  
  582. static int ctl_read(int32 *valp) {
  583.    QMSG qmsg;
  584.    
  585.    if (WinPeekMsg(Timidab,&qmsg,NULLHANDLE,0,0,0)) {
  586.       switch (qmsg.msg) {
  587.       case UM_PAUSE:
  588.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  589.      DosWaitEventSem(pausesem,-1);
  590.      return RC_NONE;
  591.       case UM_STOP:
  592.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  593.       case UM_EXIT:
  594.       case WM_QUIT:
  595.      return RC_QUIT;
  596.       case UM_PLAY:
  597.      return RC_LOAD_FILE;
  598.       case UM_RESTART:
  599.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  600.      currtime=0;
  601.      return RC_RESTART;
  602.       case UM_SKIP:
  603.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  604.      return RC_NEXT;
  605.       case UM_JUMPTO:
  606.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  607.      *valp=muldiv(LONGFROMMP(qmsg.mp1),maxtimidtime,sliderwidth);
  608.      currtime=muldiv(LONGFROMMP(qmsg.mp1),maxtime,sliderwidth);
  609.      return RC_JUMP;
  610.       case UM_PREV:
  611.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  612.      return RC_REALLY_PREVIOUS;
  613.       case UM_STEP:
  614.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  615.      *valp=play_mode->rate;
  616.      currtime+=SHORT1FROMMP(qmsg.mp1)?1000:-1000;
  617.      return SHORT1FROMMP(qmsg.mp1)?RC_FORWARD:RC_BACK;
  618.      /*      case UM_VOLUME:
  619.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  620.      *valp=LONGFROMMP(qmsg.mp1)-amplification;
  621.      return RC_CHANGE_VOLUME;*/
  622.       default:
  623.      WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0);
  624.       }
  625.    }
  626.    return RC_NONE;
  627. }
  628.  
  629. void play(char *filename, int listpos) {
  630.    int rc;
  631.    
  632.    WinEnableWindow(PAUSEwin,TRUE);
  633.    WinEnableWindow(STOPwin,TRUE);
  634.    WinEnableWindow(RESTARTwin,TRUE);
  635.    WinEnableWindow(SKIPwin,TRUE);
  636.    WinEnableWindow(BACKwin,TRUE);
  637.    WinEnableWindow(PREVwin,TRUE);
  638.    WinEnableWindow(FFWDwin,TRUE);
  639.    currtime=0;
  640.    WinStartTimer(Timidab,Frame,666,100);
  641.    while (TRUE) {
  642.       if (strstr(filename,".mid") || strstr(filename,".MID")) {
  643.      playing=PLAY_DART;
  644.      rc=play_midi_file(filename);
  645.      mciSendCommand(AmpOpenParms.usDeviceID,MCI_STOP,MCI_WAIT,
  646.             &GenericParms,0);
  647.      playing=0;
  648.       }
  649.       else {
  650.      rc=playmmos2file(filename);
  651.       }
  652.       currtime=oldtime=0;
  653.       WinSetWindowText(FILENAMETEXTwin,"");
  654.       WinSetWindowText(CURRTIMEwin,"0:00");
  655.       WinSetWindowText(TOTALTIMEwin,"0:00");
  656.       manualslide=0;
  657.       WinSendMsg(POSSLIDERwin,SLM_SETSLIDERINFO,
  658.          MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE),0);
  659.       manualslide=1;
  660.       drawticks=0;
  661.       WinInvalidateRect(POSSLIDERwin,NULL,FALSE);
  662.       timeoffset=0;
  663.       if (rc==RC_NEXT || rc==RC_REALLY_PREVIOUS || (rc==RC_TUNE_END && SHORT1FROMMR(WinSendMsg(AUTOPLAYwin,BM_QUERYCHECK,0,0))==1)) {
  664.      if (rc!=RC_REALLY_PREVIOUS) listpos++;
  665.      else
  666.         if (--listpos<0) listpos=SHORT1FROMMR(WinSendMsg(FILELISTBOXwin,LM_QUERYITEMCOUNT,0,0))-1;
  667.      WinSendMsg(FILELISTBOXwin,LM_QUERYITEMTEXT,
  668.             MPFROM2SHORT(listpos,100),filename);
  669.      if (*filename=='\0') {
  670.         listpos=0;
  671.         WinSendMsg(FILELISTBOXwin,LM_QUERYITEMTEXT,
  672.                MPFROM2SHORT(listpos,100),filename);
  673.      }
  674.       } else {
  675.      WinStopTimer(Timidab,Frame,666);
  676.      free(filename);
  677.      WinEnableWindow(PAUSEwin,FALSE);
  678.      WinEnableWindow(STOPwin,FALSE);
  679.      WinEnableWindow(RESTARTwin,FALSE);
  680.      WinEnableWindow(SKIPwin,FALSE);
  681.      WinEnableWindow(BACKwin,FALSE);
  682.      WinEnableWindow(PREVwin,FALSE);
  683.      WinEnableWindow(FFWDwin,FALSE);
  684.      return;
  685.       }
  686.    } 
  687.  
  688. static int cmsg(int type, int verbosity_level, char *fmt, ...) {
  689.    msgnode *new;
  690.    va_list ap;
  691.    int length;
  692.    char line[200];
  693.  
  694.    if ((type==CMSG_TEXT || type==CMSG_INFO || type==CMSG_WARNING) &&
  695.        ctl.verbosity<verbosity_level) return 0;
  696.    va_start(ap,fmt);
  697.    vsprintf(line,fmt,ap);
  698.    va_end(ap);
  699.    new=malloc(sizeof(void *)+1+strlen(line));
  700.    new->next=NULL;
  701.    strcpy(new->line,line);
  702.    if (msgend==NULL) msgstart=msgend=new;
  703.    else {
  704.       msgend->next=new;
  705.       msgend=new;
  706.    }
  707.    if (infoboxshown) {
  708.       length=strlen(strcpy(mleio,new->line));
  709.       mleio[length]='\r';
  710.       mleio[length+1]=' ';
  711.       mleio[length+2]='\0';
  712.       WinSendMsg(INFO_TEXTwin,MLM_IMPORT,MPFROMP(&point),MPFROMLONG(length+2));
  713.    }      
  714.    return 0;
  715. }
  716.  
  717. static void ctl_pass_playing_list(int number_of_files, char *list_of_files[]) {
  718.    LBOXINFO ListboxInfo = {LIT_END,number_of_files,0,0};
  719.    QMSG     qmsg;
  720.  
  721.    /*   FILELISTBOXwin=WinWindowFromID(Frame,FILELISTBOX);*/
  722.    WinPostMsg(FILELISTBOXwin,LM_INSERTMULTITEMS,&ListboxInfo,list_of_files);
  723.    while (WinGetMsg(Timidab,&qmsg,NULLHANDLE,0,0)) {
  724.       switch(qmsg.msg) {
  725.       case UM_EXIT: return;
  726.       case UM_PLAY:
  727.      play(qmsg.mp1,LONGFROMMP(qmsg.mp2));
  728.      break;
  729.      /*      case UM_VOLUME:
  730.      amplification=LONGFROMMP(qmsg.mp1);*/
  731.       }
  732.    }
  733. }
  734.